package org.skyui.beans;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Lob;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
import javax.persistence.Transient;

import org.skyui.accesscontrol.HumanAuthenticator;
import org.skyui.annotations.Singleton;
import org.skyui.annotations.SkyField;
import org.skyui.annotations.SkyRelation;
import org.skyui.annotations.SkyTable;
import org.skyui.beanmanagers.BeanSetManager;
import org.skyui.core.OrganizationSetup;
import org.skyui.validators.Validators;

import com.baycrypt.server.beans.people.UserBean;
import com.baycrypt.server.certmanager.CertificateManager;
import com.baycrypt.server.utils.BayCryptUtils;
import com.baycrypt.vaadinui.ProductEditions;
import com.baycrypt.vaadinui.VaadinUIApplication;

@Entity
@SkyTable(itemsCaption = "Companies", selectedItemCaption = "Manage Companies", addItemCaption = "Add Company")
@Singleton
public class OrganizationBean extends AbstractBean {

    String productEdition;

    public String getProductEdition() {
	return productEdition;
    }

    @SkyField(caption = "Company Name", read = "getName", write = "setName")
    protected String name;

    @SkyField(caption = "Country Name", read = "getCountry", write = "setCountry")
    protected String country;

    @SkyField(caption = "City Name", read = "getCity", write = "setCity")
    protected String city;

    @SkyField(caption = "Address", read = "getAddress", write = "setAddress")
    protected String address;

    @SkyField(caption = "Company ZIP code", read = "getZipCode", write = "setZipCode")
    protected String zipCode;

    // This parameters are using in certificate generation
    @Transient
    private String countryName = "US";

    public String getCountryName() {
	return countryName;
    }

    public String getStateOrProvinceName() {
	return stateOrProvinceName;
    }

    public String getLocalityName() {
	return localityName;
    }

    public String getOrganizationUnitName() {
	return organizationUnitName;
    }

    public String getCommonName() {
	return commonName;
    }

    public String getKeyPassword() {
	return keyPassword;
    }

    @Transient
    private String stateOrProvinceName = "CA";
    @Transient
    private String localityName = "SantaClara";
    @Transient
    private String organizationUnitName = "Department";
    @Transient
    private String commonName = "MyName";

    // This password is using to close RSA-key
    @Transient
    private String keyPassword = "123456";

    @OneToOne(cascade = { CascadeType.PERSIST })
    protected UserBean primaryAdmin;

    public String getName() {
	return this.name;
    }

    public String getPrimaryAttribute() {
	return getName();
    }

    public void setName(String name) {
	this.name = name;
    }

    public String getCountry() {
	return this.country;
    }

    public void setCountry(String country) {
	this.country = country;
    }

    public String getCity() {
	return this.city;
    }

    public void setCity(String city) {
	this.city = city;
    }

    public String getAddress() {
	return address;
    }

    public void setAddress(String address) {
	this.address = address;
    }

    public String getZipCode() {
	return this.zipCode;
    }

    public void setZipCode(String zipCode) {
	this.zipCode = zipCode;
    }

    public OrganizationBean() {
    }

    @Override
    public void setupTemplate() {
	this.name = "";
	this.country = "";
	this.city = "";
	this.address = "";
	this.zipCode = "";
    }
    
    @Lob
    String serverCertificate;

    public String getServerCertificate() {
	return serverCertificate;
    }

    public OrganizationBean(String name, String country,
	    String city, String address, String zipCode, UserBean primaryAdmin) {
	if (!(this.isTemplate()))
	    this.organization = this;
	this.name = name;
	this.country = country;
	this.city = city;
	this.address = address;
	this.zipCode = zipCode;
	this.primaryAdmin = primaryAdmin;
    }

    @Transient
    @SkyField(caption = "Primary Admin Email", read = "getPrimaryAdminEmail", write = "setPrimaryAdminEmail", showInView = false, validator = Validators.NewUser.class)
    String primaryAdminEmail = "";

    @Transient
    @SkyField(caption = "Primary Admin First Name", read = "getPrimaryAdminFirstName", write = "setPrimaryAdminFirstName", showInView = false)
    String primaryAdminFirstName = "";

    @SkyField(caption = "Primary Admin Last Name", read = "getPrimaryAdminLastName", write = "setPrimaryAdminLastName", showInView = false)
    @Transient
    String primaryAdminLastName = "";

    @Transient
    private OrganizationSetup organizationSetup;

    public void runOnCreateFromTemplate() {
	this.organization = this;
	if (productEdition == null)
	    throw new IllegalArgumentException("Null product edition");
	UserBean primaryAdminTemplate = (UserBean)AbstractBean.createTemplate(UserBean.class);
	primaryAdminTemplate.setAdmin(true);
	primaryAdminTemplate.setEmail(primaryAdminEmail);
	primaryAdminTemplate.setFirstName(primaryAdminFirstName);
	primaryAdminTemplate.setLastName(primaryAdminLastName);
	primaryAdminTemplate.setPassword1(password);
	primaryAdminTemplate.setOrganization(this);
	this.primaryAdmin = (UserBean) (BeanSetManager.getManager(
		UserBean.class, null))
		.cloneBeanFromTemplate(primaryAdminTemplate);
	this.primaryAdmin.setOrganization(this);
    }

    public void runBeforePersist() {
	this.serverCertificate = (new CertificateManager())
		.generateCertificate(this);
    }

    public synchronized void runAfterPersist() {
	if (organizationSetup != null)
	    organizationSetup.setup(this, primaryAdmin);
	organizationSetup = null;
    }

    public UserBean getPrimaryAdmin() {
	return this.primaryAdmin;
    }

    public String getPrimaryAdminFirstName() {
	return this.primaryAdminFirstName;
    }

    public void setPrimaryAdminFirstName(String primaryAdminFirstName) {
	this.primaryAdminFirstName = primaryAdminFirstName;
    }

    public String getPrimaryAdminLastName() {
	return this.primaryAdminLastName;
    }

    public void setPrimaryAdminLastName(String primaryAdminLastName) {
	this.primaryAdminLastName = primaryAdminLastName;
    }

    public String getPrimaryAdminEmail() {
	return this.primaryAdminEmail;
    }

    public void setPrimaryAdminEmail(String primaryAdminEmail) {
	this.primaryAdminEmail = primaryAdminEmail;
    }

    @SkyField(caption = "Set Primary Admin Password", read = "getPassword1", write = "setPassword1", password = true, showInView = false)
    public String getPassword1() {
	return "";
    }

    @SkyField(caption = "Retype Primary Admin Password", read = "getPassword2", write = "setPassword2", passwordVerify = true, showInView = false)
    public String getPassword2() {
	return "";
    }

    @Transient
    String password;

    public void setPassword1(String password1) {
	if (password1 != null && password1.length() != 0) {
	    this.password = password1;
	}
    }

    public void setPassword2(String password2) {
    }

    public void setOrganizationSetup(OrganizationSetup organizationSetup) {
	this.organizationSetup = organizationSetup;

    }

    public OrganizationSetup getOrganizationSetup() {
	return organizationSetup;
    }

    public void setProductEdition(String productEdition) {
	this.productEdition = productEdition;
    }
    
    @ManyToMany(cascade = { CascadeType.PERSIST })
    Set<OrganizationBean> organizationFriends = new HashSet<OrganizationBean>();
    
    public Set<OrganizationBean> getOrganizationFriends(){
	return organizationFriends;
    }

    
}
